home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 44 / PC Actual CD 44.iso / Linux / Cygwin / full.exe / Disk1 / data1.cab / Tools / share / tix4.1 / ComboBox.tcl < prev    next >
Encoding:
Text File  |  1998-12-04  |  34.0 KB  |  1,550 lines

  1. # tixCombobox --
  2. #
  3. #    A combobox widget is basically a listbox widget with an entry
  4. #    widget.
  5. #
  6. #
  7. # Copyright (c) 1996, Expert Interface Technologies
  8. #
  9. # See the file "license.terms" for information on usage and redistribution
  10. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  11.  
  12. tixWidgetClass tixComboBox {
  13.     -classname TixComboBox
  14.     -superclass tixLabelWidget
  15.     -method {
  16.     addhistory align appendhistory flash invoke insert pick popdown
  17.     }
  18.     -flag {
  19.     -anchor -arrowbitmap -browsecmd -command -crossbitmap
  20.     -disablecallback -disabledforeground -dropdown -editable
  21.     -fancy -grab -histlimit -historylimit -history -listcmd
  22.     -listwidth -prunehistory -selection -selectmode -state
  23.     -tickbitmap -validatecmd -value -variable
  24.     }
  25.     -static {
  26.     -dropdown -fancy
  27.     }
  28.     -forcecall {
  29.     -variable -selectmode -state
  30.     }
  31.     -configspec {
  32.     {-arrowbitmap arrowBitmap ArrowBitmap ""}
  33.     {-anchor anchor Anchor w}
  34.     {-browsecmd browseCmd BrowseCmd ""}
  35.         {-command command Command ""}
  36.     {-crossbitmap crossBitmap CrossBitmap ""}
  37.     {-disablecallback disableCallback DisableCallback 0 tixVerifyBoolean}
  38.     {-disabledforeground disabledForeground DisabledForeground #606060}
  39.     {-dropdown dropDown DropDown true tixVerifyBoolean}
  40.     {-editable editable Editable false tixVerifyBoolean}
  41.     {-fancy fancy Fancy false tixVerifyBoolean}
  42.     {-grab grab Grab global}
  43.     {-listcmd listCmd ListCmd ""}
  44.     {-listwidth listWidth ListWidth ""}
  45.     {-historylimit historyLimit HistoryLimit ""}
  46.     {-history history History false tixVerifyBoolean}
  47.     {-prunehistory pruneHistory PruneHistory true tixVerifyBoolean}
  48.     {-selectmode selectMode SelectMode browse}
  49.     {-selection selection Selection ""}
  50.         {-state state State normal}
  51.     {-validatecmd validateCmd ValidateCmd ""}
  52.     {-value value Value ""}
  53.     {-variable variable Variable ""}
  54.     {-tickbitmap tickBitmap TickBitmap ""}
  55.     }
  56.     -alias {
  57.     {-histlimit -historylimit}
  58.     }
  59.     -default {
  60.     {*Entry.relief                sunken}
  61.         {*TixScrolledListBox.scrollbar        auto}
  62.     {*Listbox.exportSelection        false}
  63.     {*Listbox.takeFocus            false}
  64.     {*shell.borderWidth            2}
  65.     {*shell.relief                raised}
  66.     {*shell.cursor                arrow}
  67.     {*Button.anchor                c}
  68.     {*Button.borderWidth            1}
  69.     {*Button.highlightThickness        0}
  70.     {*Button.padX                0}
  71.     {*Button.padY                0}
  72.     {*tick.width                18}
  73.     {*tick.height                18}
  74.     {*cross.width                18}
  75.     {*cross.height                18}
  76.     {*arrow.anchor                c}
  77.     {*arrow.width                15}
  78.     {*arrow.height                18}
  79.     {*Entry.background            #c3c3c3}
  80.     {*Label.font         -Adobe-Helvetica-Bold-R-Normal--*-120-*-*-*-*-*-*}
  81.     }
  82. }
  83.  
  84. # States: normal numbers: for dropdown style
  85. #         d+digit(s)    : for non-dropdown style
  86. #
  87. proc tixComboBox:InitWidgetRec {w} {
  88.     upvar #0 $w data
  89.  
  90.     tixChainMethod $w InitWidgetRec
  91.  
  92.     set data(curIndex)    ""
  93.     set data(varInited)      0
  94.     set data(state)       none
  95.     set data(ignore)      0
  96.  
  97.     if {$data(-history)} {
  98.         set data(-editable) 1
  99.     }
  100.  
  101.     if ![string compare $data(-arrowbitmap) ""] {
  102.     set data(-arrowbitmap) [tix getbitmap cbxarrow]
  103.     }
  104.     if ![string compare $data(-crossbitmap) ""] {
  105.     set data(-crossbitmap) [tix getbitmap cross]
  106.     }
  107.     if ![string compare $data(-tickbitmap) ""] {
  108.     set data(-tickbitmap) [tix getbitmap tick]
  109.     }
  110. }
  111.  
  112. proc tixComboBox:ConstructFramedWidget {w frame} {
  113.     upvar #0 $w data
  114.  
  115.     tixChainMethod $w ConstructFramedWidget $frame
  116.  
  117.     if {$data(-dropdown)} {
  118.     tixComboBox:ConstructEntryFrame $w $frame
  119.     tixComboBox:ConstructListShell $w
  120.     } else {
  121.     set f1 [frame $frame.f1]
  122.     set f2 [frame $frame.f2]
  123.  
  124.     tixComboBox:ConstructEntryFrame $w $f1
  125.     tixComboBox:ConstructListFrame  $w $f2
  126.     pack $f1 -side top -pady 2 -fill x
  127.     pack $f2 -side top -pady 2 -fill both -expand yes
  128.     }
  129. }
  130.  
  131. proc tixComboBox:ConstructEntryFrame {w frame} {
  132.     upvar #0 $w data
  133.  
  134.     # (1) The entry
  135.     #
  136.     set data(w:entry) [entry $frame.entry]
  137.  
  138.     if {!$data(-editable)} {
  139.     set bg [$w cget -bg]
  140.     $data(w:entry) config -bg $bg -state disabled -takefocus 1
  141.     }
  142.  
  143.     # This is used during "config-state"
  144.     #
  145.     set data(entryfg) [$data(w:entry) cget -fg]
  146.  
  147.     # (2) The dropdown button, not necessary when not in dropdown mode
  148.     #
  149.     set data(w:arrow) [button $frame.arrow -bitmap $data(-arrowbitmap)]
  150.     if {!$data(-dropdown)} {
  151.     set xframe [frame $frame.xframe -width 19]
  152.     }
  153.  
  154.     # (3) The fancy tick and cross buttons
  155.     #
  156.     if {$data(-fancy)} {
  157.     if {$data(-editable)} {
  158.            set data(w:cross)  [button $frame.cross -bitmap $data(-crossbitmap)]
  159.        set data(w:tick)   [button $frame.tick  -bitmap $data(-tickbitmap)]
  160.  
  161.        pack $frame.cross -side left -padx 1
  162.        pack $frame.tick  -side left -padx 1
  163.     } else {
  164.        set data(w:tick)   [button $frame.tick  -bitmap $data(-tickbitmap)]
  165.        pack $frame.tick  -side left -padx 1
  166.     }
  167.     }
  168.  
  169.     if {$data(-dropdown)} {
  170.     pack $data(w:arrow) -side right -padx 1
  171.     foreach wid "$data(w:frame) $data(w:label)" {
  172.         tixAddBindTag $wid TixComboWid
  173.         tixSetMegaWidget $wid $w TixComboBox
  174.     }
  175.     } else {
  176.     pack $xframe -side right -padx 1
  177.     }
  178.     pack $frame.entry -side right -fill x -expand yes -padx 1
  179. }
  180.  
  181. proc tixComboBox:ConstructListShell {w} {
  182.     upvar #0 $w data
  183.  
  184.     # Create the shell and the list
  185.     #------------------------------
  186.     set data(w:shell) [menu $w.shell -bd 2 -relief raised -tearoff 0]
  187.     wm overrideredirect $data(w:shell) 1
  188.     wm withdraw $data(w:shell)
  189.  
  190.     set data(w:slistbox) [tixScrolledListBox $data(w:shell).slistbox \
  191.     -anchor $data(-anchor) -scrollbarspace y \
  192.     -options {listbox.selectMode "browse"}]
  193.  
  194.     set data(w:listbox) [$data(w:slistbox) subwidget listbox]
  195.  
  196.     pack $data(w:slistbox) -expand yes -fill both -padx 2 -pady 2
  197. }
  198.  
  199. proc tixComboBox:ConstructListFrame {w frame} {
  200.     upvar #0 $w data
  201.  
  202.     set data(w:slistbox) [tixScrolledListBox $frame.slistbox \
  203.     -anchor $data(-anchor)]
  204.  
  205.     set data(w:listbox) [$data(w:slistbox) subwidget listbox]
  206.  
  207.     pack $data(w:slistbox) -expand yes -fill both
  208. }
  209.  
  210.  
  211. proc tixComboBox:SetBindings {w} {
  212.     upvar #0 $w data
  213.  
  214.     tixChainMethod $w SetBindings
  215.  
  216.     # (1) Fix the bindings for the combobox
  217.     #
  218.     bindtags $w "$w TixComboBox [winfo toplevel $w] all"
  219.  
  220.     # (2) The entry subwidget
  221.     #
  222.     tixSetMegaWidget $data(w:entry) $w TixComboBox
  223.  
  224.     bindtags $data(w:entry) [list $data(w:entry) Entry TixComboEntry\
  225.     TixComboWid [winfo toplevel $data(w:entry)] all]
  226.  
  227.     # (3) The listbox and slistbox
  228.     #
  229.     $data(w:slistbox) config -browsecmd \
  230.     "tixComboBox:LbBrowse  $w"
  231.     $data(w:slistbox) config -command\
  232.     "tixComboBox:LbCommand $w"
  233.     $data(w:listbox) config -takefocus 0
  234.  
  235.     tixAddBindTag $data(w:listbox)  TixComboLb
  236.     tixAddBindTag $data(w:slistbox) TixComboLb
  237.     tixSetMegaWidget $data(w:listbox)  $w TixComboBox
  238.     tixSetMegaWidget $data(w:slistbox) $w TixComboBox
  239.  
  240.     # (4) The buttons
  241.     #
  242.     if {$data(-dropdown)} {
  243.     $data(w:arrow) config -takefocus 0
  244.     tixAddBindTag $data(w:arrow) TixComboArrow
  245.     tixSetMegaWidget $data(w:arrow) $w TixComboBox
  246.  
  247.     bind $data(w:root) <1>                "tixComboBox:RootDown $w"
  248.     bind $data(w:root) <ButtonRelease-1>  "tixComboBox:RootUp   $w"
  249.     }
  250.  
  251.     if {$data(-fancy)} {
  252.     if {$data(-editable)} {
  253.         $data(w:cross) config -command "tixComboBox:CrossBtn $w" \
  254.         -takefocus 0
  255.     }
  256.     $data(w:tick) config -command "tixComboBox:Invoke $w" -takefocus 0
  257.     }
  258.  
  259.     if {$data(-dropdown)} {
  260.     set data(state) 0
  261.     } else {
  262.     set data(state) n0
  263.     }    
  264. }
  265.  
  266. proc tixComboBoxBind {} {
  267.     #----------------------------------------------------------------------
  268.     # The class bindings for the TixComboBox
  269.     #
  270.     tixBind TixComboBox <Escape> {
  271.     if [tixComboBox:EscKey %W] {
  272.         break
  273.     }
  274.     }
  275.     tixBind TixComboBox <Configure> {
  276.     tixWidgetDoWhenIdle tixComboBox:align %W
  277.     }
  278.     # Only the two "linear" detail_fields  are for tabbing (moving) among
  279.     # widgets inside the same toplevel. Other detail_fields are sort
  280.     # of irrelevant
  281.     #
  282.     tixBind TixComboBox <FocusOut>  {
  283.     if {![string compare %d NotifyNonlinear] ||
  284.         ![string compare %d NotifyNonlinearVirtual]} {
  285.  
  286.         if [info exists %W(cancelTab)] {
  287.         unset %W(cancelTab)
  288.         } else {
  289.         if [string compare [set %W(-state)] disabled] {
  290.             if [string compare [set %W(-selection)] [set %W(-value)]] {
  291.             tixComboBox:Invoke %W
  292.             }
  293.         }
  294.         }
  295.     }
  296.     }
  297.     tixBind TixComboBox <FocusIn>  {
  298.     if {[tixStrEq %d NotifyNonlinear] || 
  299.         [tixStrEq %d NotifyNonlinearVirtual]} {
  300.  
  301.         focus [%W subwidget entry]
  302.  
  303.         # CYGNUS LOCAL: Setting the selection if there is no data
  304.         # causes backspace to misbehave.
  305.         if {[[set %W(w:entry)] get] != ""} {
  306.         [set %W(w:entry)] selection from 0
  307.         [set %W(w:entry)] selection to end
  308.         }
  309.     }
  310.     }
  311.  
  312.     #----------------------------------------------------------------------
  313.     # The class tixBindings for the arrow button widget inside the TixComboBox
  314.     #
  315.  
  316.     tixBind TixComboArrow <1>               {
  317.     tixComboBox:ArrowDown [tixGetMegaWidget %W TixComboBox]
  318.     }
  319.     tixBind TixComboArrow <ButtonRelease-1> {
  320.     tixComboBox:ArrowUp   [tixGetMegaWidget %W TixComboBox]
  321.     }
  322.     tixBind TixComboArrow <Escape>          {
  323.     if [tixComboBox:EscKey [tixGetMegaWidget %W TixComboBox]] {
  324.         break
  325.     }
  326.     }
  327.  
  328.  
  329.     #----------------------------------------------------------------------
  330.     # The class tixBindings for the entry widget inside the TixComboBox
  331.     #
  332.     tixBind TixComboEntry <Up>        {
  333.     tixComboBox:EntDirKey [tixGetMegaWidget %W TixComboBox] up
  334.     }
  335.     tixBind TixComboEntry <Down>    {
  336.     tixComboBox:EntDirKey [tixGetMegaWidget %W TixComboBox] down
  337.     }
  338.     tixBind TixComboEntry <Prior>    {
  339.     tixComboBox:EntDirKey [tixGetMegaWidget %W TixComboBox] pageup
  340.     }
  341.     tixBind TixComboEntry <Next>    {
  342.     tixComboBox:EntDirKey [tixGetMegaWidget %W TixComboBox] pagedown
  343.     }
  344.     tixBind TixComboEntry <Return>    {    
  345.     tixComboBox:EntReturnKey [tixGetMegaWidget %W TixComboBox]
  346.     }
  347.     tixBind TixComboEntry <KeyPress>    {
  348.     tixComboBox:EntKeyPress [tixGetMegaWidget %W TixComboBox]
  349.     }
  350.     tixBind TixComboEntry <Escape>     {
  351.     if [tixComboBox:EscKey [tixGetMegaWidget %W TixComboBox]] {
  352.         break
  353.     }
  354.     }
  355.     tixBind TixComboEntry <Tab>     {
  356.     if {[set [tixGetMegaWidget %W TixComboBox](-state)] != "disabled"} {
  357.         if [tixComboBox:EntTab [tixGetMegaWidget %W TixComboBox]] {
  358.         break
  359.         }
  360.     }
  361.     }
  362.     tixBind TixComboEntry <1>    {
  363.     if {[set [tixGetMegaWidget %W TixComboBox](-state)] != "disabled"} {
  364.         focus %W
  365.     }
  366.     }
  367.     tixBind TixComboEntry <ButtonRelease-2>    {
  368.     tixComboBox:EntKeyPress [tixGetMegaWidget %W TixComboBox]
  369.     }
  370.  
  371.     #----------------------------------------------------------------------
  372.     # The class bindings for the listbox subwidget
  373.     #
  374.  
  375.     tixBind TixComboWid <Escape> {
  376.     if [tixComboBox:EscKey [tixGetMegaWidget %W TixComboBox]] {
  377.         break
  378.     }
  379.     }
  380.  
  381.     #----------------------------------------------------------------------
  382.     # The class bindings for some widgets inside ComboBox
  383.     #
  384.     tixBind TixComboWid <ButtonRelease-1> {
  385.     tixComboBox:WidUp [tixGetMegaWidget %W TixComboBox]
  386.     }
  387.     tixBind TixComboWid <Escape> {
  388.     if [tixComboBox:EscKey [tixGetMegaWidget %W TixComboBox]] {
  389.         break
  390.     }
  391.     }
  392. }
  393.  
  394. #----------------------------------------------------------------------
  395. #              Cooked events
  396. #----------------------------------------------------------------------
  397. proc tixComboBox:ArrowDown {w} {
  398.     upvar #0 $w data
  399.  
  400.     if ![string compare $data(-state) disabled] {
  401.     return
  402.     }
  403.     
  404.     case $data(state) {
  405.     {0} {
  406.         tixComboBox:GoState 1 $w
  407.     }
  408.     {2} {
  409.         tixComboBox:GoState 19 $w
  410.     }
  411.     default {
  412.         tixComboBox:StateError $w
  413.     }
  414.     }
  415. }
  416.  
  417. proc tixComboBox:ArrowUp {w} {
  418.     upvar #0 $w data
  419.     
  420.     case $data(state) {
  421.     {1} {
  422.         tixComboBox:GoState 2 $w
  423.     }
  424.     {19} {
  425.         # data(ignore) was already set in state 19
  426.         tixComboBox:GoState 4 $w
  427.     }
  428.     {5} {
  429.         tixComboBox:GoState 13 $w
  430.     }
  431.     default {
  432.         tixComboBox:StateError $w
  433.     }
  434.     }
  435. }
  436.  
  437. proc tixComboBox:RootDown {w} {
  438.     upvar #0 $w data
  439.     
  440.     case $data(state) {
  441.     {0} {
  442.         # Ignore
  443.     }
  444.     {2} {
  445.         tixComboBox:GoState 3 $w
  446.     }
  447.     default {
  448.         tixComboBox:StateError $w
  449.     }
  450.     }
  451. }
  452.  
  453. proc tixComboBox:RootUp {w} {
  454.     upvar #0 $w data
  455.     
  456.     case $data(state) {
  457.     {1} {
  458.         tixComboBox:GoState 12 $w
  459.     }
  460.     {3} {
  461.         # data(ignore) was already set in state 3
  462.         tixComboBox:GoState 4 $w
  463.     }
  464.     {5} {
  465.         tixComboBox:GoState 7 $w
  466.     }
  467.     default {
  468.         tixComboBox:StateError $w
  469.     }
  470.     }
  471. }
  472.  
  473. proc tixComboBox:WidUp {w} {
  474.     upvar #0 $w data
  475.     
  476.     case $data(state) {
  477.     {1} {
  478.         tixComboBox:GoState 12 $w
  479.     }
  480.     {5} {
  481.         tixComboBox:GoState 13 $w
  482.     }
  483.     }
  484. }
  485.  
  486. proc tixComboBox:LbBrowse {w args} {
  487.     upvar #0 $w data
  488.  
  489.     set event [tixEvent type]
  490.     set x [tixEvent flag x]
  491.     set y [tixEvent flag y]
  492.     set X [tixEvent flag X]
  493.     set Y [tixEvent flag Y]
  494.  
  495.     if ![string compare $data(-state) disabled] {
  496.     return
  497.     }
  498.  
  499.     case $event {
  500.     <1> {
  501.         case $data(state) {
  502.         {2} {
  503.             tixComboBox:GoState 5 $w $x $y $X $Y
  504.         }
  505.         {5} {
  506.             tixComboBox:GoState 5 $w $x $y $X $Y
  507.         }
  508.         {n0} {
  509.             tixComboBox:GoState n6 $w $x $y $X $Y
  510.         }
  511.         default {
  512.             tixComboBox:StateError $w
  513.         }
  514.         }
  515.     }
  516.     <ButtonRelease-1> {
  517.         case $data(state) {
  518.         {5} {
  519.             tixComboBox:GoState 6 $w $x $y $X $Y
  520.         }
  521.         {n6} {
  522.             tixComboBox:GoState n0 $w
  523.         }
  524.         default {
  525.             tixComboBox:StateError $w
  526.         }
  527.         }
  528.     }
  529.     default {
  530.         # Must be a motion event
  531.         case $data(state) {
  532.         {1} {
  533.             tixComboBox:GoState 9 $w $x $y $X $Y
  534.         }
  535.         {5} {
  536.             tixComboBox:GoState 5 $w $x $y $X $Y
  537.         }
  538.         {n6} {
  539.             tixComboBox:GoState n6 $w $x $y $X $Y
  540.         }
  541.         default {
  542.             tixComboBox:StateError $w
  543.         }
  544.         }
  545.     }
  546.     }
  547. }
  548.  
  549. proc tixComboBox:LbCommand {w} {
  550.     upvar #0 $w data
  551.  
  552.     case $data(state) {
  553.     {n0} {
  554.         tixComboBox:GoState n1 $w
  555.     }
  556.     }
  557. }
  558.  
  559. #----------------------------------------------------------------------
  560. #           General keyboard event
  561.  
  562. # returns 1 if the combobox is in some special state and the Escape key
  563. # shouldn't be handled by the toplevel bind tag. As a result, when a combobox
  564. # is popped up in a dialog box, Escape will popdown the combo. If the combo
  565. # is not popped up, Escape will invoke the toplevel bindtag (which can
  566. # pop down the dialog box)
  567. #
  568. proc tixComboBox:EscKey {w} {
  569.     upvar #0 $w data
  570.  
  571.     if ![string compare $data(-state) disabled] {
  572.     return
  573.     }
  574.  
  575.     case $data(state) {
  576.     {0} {
  577.         tixComboBox:GoState 17 $w
  578.     }
  579.     {2} {
  580.         tixComboBox:GoState 16 $w
  581.         return 1
  582.     }
  583.     {n0} {
  584.         tixComboBox:GoState n4 $w
  585.     }
  586.     default {
  587.         # ignore
  588.         return 1
  589.     }
  590.     }
  591.  
  592.     return 0
  593. }
  594.  
  595. #----------------------------------------
  596. # Keyboard events
  597. #----------------------------------------
  598. proc tixComboBox:EntDirKey {w dir} {
  599.     upvar #0 $w data
  600.  
  601.     if ![string compare $data(-state) disabled] {
  602.     return
  603.     }
  604.  
  605.     case $data(state) {
  606.     {0} {
  607.         tixComboBox:GoState 10 $w $dir
  608.     }
  609.     {2} {
  610.         tixComboBox:GoState 11 $w $dir
  611.     }
  612.     {5} {
  613.         # ignore
  614.     }
  615.     {n0} {
  616.         tixComboBox:GoState n3 $w $dir
  617.     }
  618.     }
  619. }
  620.  
  621. proc tixComboBox:EntReturnKey {w} {
  622.     upvar #0 $w data
  623.  
  624.     if ![string compare $data(-state) disabled] {
  625.     return
  626.     }
  627.  
  628.     case $data(state) {
  629.     {0} {
  630.         tixComboBox:GoState 14 $w
  631.     }
  632.     {2} {
  633.         tixComboBox:GoState 15 $w
  634.     }
  635.     {5} {
  636.         # ignore
  637.     }
  638.     {n0} {
  639.         tixComboBox:GoState n1 $w
  640.     }
  641.     }
  642. }
  643.  
  644. # Return 1 == break from the binding == no keyboard focus traversal
  645. proc tixComboBox:EntTab {w} {
  646.     upvar #0 $w data
  647.  
  648.     case $data(state) {
  649.     {0} {
  650.         tixComboBox:GoState 14 $w
  651.         set data(cancelTab) ""
  652.         return 0
  653.     }
  654.     {2} {
  655.         tixComboBox:GoState 15 $w
  656.         set data(cancelTab) ""
  657.         return 0
  658.     }
  659.     {n0} {
  660.         tixComboBox:GoState n1 $w
  661.         set data(cancelTab) ""
  662.         return 0
  663.     }
  664.     default {
  665.         return 1
  666.     }
  667.     }
  668. }
  669.  
  670. proc tixComboBox:EntKeyPress {w} {
  671.     upvar #0 $w data
  672.  
  673.     if {!$data(-editable)} {
  674.     return
  675.     }
  676.     if [tixStrEq $data(-state) disabled] {
  677.     return
  678.     }
  679.  
  680.     case $data(state) {
  681.     {0 2 n0} {
  682.         tixComboBox:ClearListboxSelection $w
  683.         tixComboBox:SetSelection $w [$data(w:entry) get] 0 0
  684.     }
  685.  
  686.     }
  687. }
  688.  
  689. #----------------------------------------------------------------------
  690.  
  691. proc tixComboBox:HandleDirKey {w dir} {
  692.     upvar #0 $w data
  693.  
  694.     if [tixComboBox:CheckListboxSelection $w] {
  695.     case $dir {
  696.         "up" {
  697.         tkListboxUpDown $data(w:listbox) -1
  698.         set data(curIndex) [lindex [$data(w:listbox) curselection] 0]
  699.         tixComboBox:SetSelectionFromListbox $w
  700.         }
  701.         "down" {
  702.         tkListboxUpDown $data(w:listbox)  1
  703.         set data(curIndex) [lindex [$data(w:listbox) curselection] 0]
  704.         tixComboBox:SetSelectionFromListbox $w
  705.         }
  706.         "pageup" {
  707.         $data(w:listbox) yview scroll -1 pages
  708.         }
  709.         "pagedown" {
  710.         $data(w:listbox) yview scroll  1 pages
  711.         }
  712.     }
  713.     } else {
  714.     # There wasn't good selection in the listbox.
  715.     #
  716.     tixComboBox:SetSelectionFromListbox $w
  717.     }
  718. }
  719.  
  720. proc tixComboBox:Invoke {w} {
  721.     upvar #0 $w data
  722.  
  723.     tixComboBox:SetValue $w $data(-selection)
  724.     if ![winfo exists $w] {
  725.     return
  726.     }
  727.  
  728.     if {$data(-history)} {
  729.     tixComboBox:addhistory $w $data(-value)
  730.     set data(curIndex) 0
  731.     }
  732.     $data(w:entry) selection from 0
  733.     $data(w:entry) selection to end
  734.     $data(w:entry) icursor end
  735. }
  736.  
  737. #----------------------------------------------------------------------
  738. #                   MAINTAINING THE -VALUE
  739. #----------------------------------------------------------------------
  740. proc tixComboBox:SetValue {w newValue {noUpdate 0} {updateEnt 1}} {
  741.     upvar #0 $w data
  742.  
  743.     if {$data(-validatecmd) != ""} {
  744.        set data(-value) [tixEvalCmdBinding $w $data(-validatecmd) "" $newValue]
  745.     } else {
  746.     set data(-value) $newValue
  747.     }
  748.  
  749.     if {! $noUpdate} {
  750.     tixVariable:UpdateVariable $w
  751.     }
  752.  
  753.     if {$updateEnt} {
  754.     if {!$data(-editable)} {
  755.         $data(w:entry) delete 0 end
  756.         $data(w:entry) insert 0 $data(-value)
  757.     }
  758.     }
  759.  
  760.     if {!$data(-disablecallback) && $data(-command) != ""} {
  761.     if {![info exists data(varInited)]} {
  762.         set bind(specs) {%V}
  763.         set bind(%V)    $data(-value)
  764.  
  765.         tixEvalCmdBinding $w $data(-command) bind $data(-value)
  766.         if ![winfo exists $w] {
  767.         # The user destroyed the window!
  768.         return
  769.         }
  770.     }
  771.     }
  772.  
  773.     set data(-selection) $data(-value)
  774.     if {$updateEnt} {
  775.     tixSetEntry $data(w:entry) $data(-value)
  776.  
  777.     if {$data(-anchor) == "e"} {
  778.         tixComboBox:EntryAlignEnd $w
  779.     }
  780.     }
  781. }
  782.  
  783. # markSel: should the all the text in the entry be highlighted?
  784. #
  785. proc tixComboBox:SetSelection {w value {markSel 1} {setent 1}} {
  786.     upvar #0 $w data
  787.  
  788.     if {$setent} {
  789.     tixSetEntry $data(w:entry) $value
  790.     }
  791.     set data(-selection) $value
  792.  
  793.     if {$data(-selectmode) == "browse"} {
  794.     if {$markSel} {
  795.         $data(w:entry) selection range 0 end
  796.     }
  797.     if {$data(-browsecmd) != ""} {
  798.         set bind(specs) {%V}
  799.         set bind(%V)    [$data(w:entry) get]
  800.         tixEvalCmdBinding $w $data(-browsecmd) bind [$data(w:entry) get]
  801.     }
  802.     } else {
  803.     tixComboBox:SetValue $w $value 0 0
  804.     }
  805. }
  806.  
  807. proc tixComboBox:ClearListboxSelection {w} {
  808.     upvar #0 $w data
  809.  
  810.     $data(w:listbox) selection clear 0 end
  811. }
  812.  
  813. proc tixComboBox:UpdateListboxSelection {w index} {
  814.     upvar #0 $w data
  815.  
  816.     if {$index != ""} {
  817.     $data(w:listbox) selection set $index
  818.     $data(w:listbox) selection anchor $index
  819.     }
  820. }
  821.  
  822.  
  823. proc tixComboBox:Cancel {w} {
  824.     upvar #0 $w data
  825.  
  826.     tixSetEntry $data(w:entry) $data(-value)
  827.     tixComboBox:SetSelection $w $data(-value)
  828.  
  829.     if {"x[tixComboBox:LbGetSelection $w]" != "x$data(-selection)"} {
  830.     tixComboBox:ClearListboxSelection $w
  831.     }
  832. }
  833.  
  834. proc tixComboBox:flash {w} {
  835.     tixComboBox:BlinkEntry $w
  836. }
  837.  
  838. # Make the entry blink when the user selects a choice
  839. #
  840. proc tixComboBox:BlinkEntry {w} {
  841.     upvar #0 $w data
  842.  
  843.     if {![info exists data(entryBlacken)]} {
  844.     set old_bg [$data(w:entry) cget -bg]
  845.     set old_fg [$data(w:entry) cget -fg]
  846.  
  847.     $data(w:entry) config -fg $old_bg
  848.     $data(w:entry) config -bg $old_fg
  849.  
  850.     set data(entryBlacken) 1
  851.     after 50 tixComboBox:RestoreBlink $w [list $old_bg] [list $old_fg]
  852.     }
  853. }
  854.  
  855. proc tixComboBox:RestoreBlink {w old_bg old_fg} {
  856.     upvar #0 $w data
  857.  
  858.     if {[info exists data(w:entry)] && [winfo exists $data(w:entry)]} {
  859.     $data(w:entry) config -fg $old_fg
  860.     $data(w:entry) config -bg $old_bg
  861.     }
  862.  
  863.     if [info exists data(entryBlacken)] {
  864.     unset data(entryBlacken)
  865.     }
  866. }
  867.  
  868. #----------------------------------------
  869. #  Handle events inside the list box
  870. #----------------------------------------
  871.  
  872. proc tixComboBox:LbIndex {w {flag ""}} {
  873.     upvar #0 $w data
  874.  
  875.     set sel [lindex [$data(w:listbox) curselection] 0]
  876.     if {$sel != ""} {
  877.     return $sel
  878.     } else {
  879.     if {$flag == "emptyOK"} {
  880.         return ""
  881.     } else {
  882.         return 0
  883.     }
  884.     }
  885. }
  886.  
  887. #----------------------------------------------------------------------
  888. #
  889. #            STATE MANIPULATION
  890. #
  891. #----------------------------------------------------------------------
  892. proc tixComboBox:GoState-0 {w} {
  893.     upvar #0 $w data
  894. }
  895.  
  896. proc tixComboBox:GoState-1 {w} {
  897.     upvar #0 $w data
  898.  
  899.     tixComboBox:Popup $w
  900. }
  901.  
  902. proc tixComboBox:GoState-2 {w} {
  903.     upvar #0 $w data
  904.  
  905. }
  906.  
  907. proc tixComboBox:GoState-3 {w} {
  908.     upvar #0 $w data
  909.  
  910.     set data(ignore) 1
  911.     tixComboBox:Popdown $w
  912. }
  913.  
  914. proc tixComboBox:GoState-4 {w} {
  915.     upvar #0 $w data
  916.  
  917.     tixComboBox:Ungrab $w
  918.     if {$data(ignore)} {
  919.     tixComboBox:Cancel $w
  920.     } else {
  921.     tixComboBox:Invoke $w
  922.     }
  923.     tixComboBox:GoState 0 $w
  924. }
  925.  
  926. proc tixComboBox:GoState-5 {w x y X Y} {
  927.     upvar #0 $w data
  928.  
  929.     tixComboBox:LbSelect $w $x $y $X $Y
  930. }
  931.  
  932. proc tixComboBox:GoState-6 {w x y X Y} {
  933.     upvar #0 $w data
  934.  
  935.     tixComboBox:Popdown $w
  936.  
  937.     if [tixWithinWindow $data(w:shell) $X $Y] {
  938.     set data(ignore) 0
  939.     } else {
  940.     set data(ignore) 1
  941.     }
  942.  
  943.     tixComboBox:GoState 4 $w
  944. }
  945.  
  946. proc tixComboBox:GoState-7 {w} {
  947.     upvar #0 $w data
  948.  
  949.     tixComboBox:Popdown $w
  950.     set data(ignore) 1
  951.     catch {
  952.     global tkPriv
  953.     if {$tkPriv(afterId) != ""} {
  954.         tkCancelRepeat
  955.     }
  956.     }
  957.  
  958.     set data(ignore) 1
  959.     tixComboBox:GoState 4 $w
  960. }
  961.  
  962. proc tixComboBox:GoState-9 {w x y X Y} {
  963.     upvar #0 $w data
  964.  
  965.     catch {
  966.     tkButtonUp $data(w:arrow)
  967.     }
  968.     tixComboBox:GoState 5 $w $x $y $X $Y
  969. }
  970.  
  971. proc tixComboBox:GoState-10 {w dir} {
  972.     upvar #0 $w data
  973.  
  974.     tixComboBox:Popup $w
  975.     if {![tixComboBox:CheckListboxSelection $w]} {
  976.     # There wasn't good selection in the listbox.
  977.     #
  978.     tixComboBox:SetSelectionFromListbox $w
  979.     }
  980.  
  981.     tixComboBox:GoState 2 $w
  982. }
  983.  
  984. proc tixComboBox:GoState-11 {w dir} {
  985.     upvar #0 $w data
  986.  
  987.     tixComboBox:HandleDirKey $w $dir
  988.  
  989.     tixComboBox:GoState 2 $w
  990. }
  991.  
  992. proc tixComboBox:GoState-12 {w} {
  993.     upvar #0 $w data
  994.  
  995.     catch {
  996.     tkButtonUp $data(w:arrow)
  997.     }
  998.  
  999.     tixComboBox:GoState 2 $w
  1000. }
  1001.  
  1002. proc tixComboBox:GoState-13 {w} {
  1003.     upvar #0 $w data
  1004.  
  1005.     catch {
  1006.     global tkPriv
  1007.     if {$tkPriv(afterId) != ""} {
  1008.         tkCancelRepeat
  1009.     }
  1010.     }
  1011.     tixComboBox:GoState 2 $w
  1012. }
  1013.  
  1014. proc tixComboBox:GoState-14 {w} {
  1015.     upvar #0 $w data
  1016.  
  1017.     tixComboBox:Invoke $w
  1018.     tixComboBox:GoState 0 $w
  1019. }
  1020.  
  1021. proc tixComboBox:GoState-15 {w} {
  1022.     upvar #0 $w data
  1023.  
  1024.     tixComboBox:Popdown $w
  1025.     set data(ignore) 0
  1026.     tixComboBox:GoState 4 $w
  1027. }
  1028.  
  1029. proc tixComboBox:GoState-16 {w} {
  1030.     upvar #0 $w data
  1031.  
  1032.     tixComboBox:Popdown $w
  1033.     tixComboBox:Cancel $w
  1034.     set data(ignore) 1
  1035.     tixComboBox:GoState 4 $w
  1036. }
  1037.  
  1038. proc tixComboBox:GoState-17 {w} {
  1039.     upvar #0 $w data
  1040.  
  1041.     tixComboBox:Cancel $w
  1042.     tixComboBox:GoState 0 $w
  1043. }
  1044.  
  1045. proc tixComboBox:GoState-19 {w} {
  1046.     upvar #0 $w data
  1047.  
  1048.     if {"x$data(-selection)" != "x$data(-value)"} {
  1049.     set data(ignore) 0
  1050.     } else {
  1051.     set data(ignore) 1
  1052.     }
  1053.     tixComboBox:Popdown $w
  1054. }
  1055.  
  1056. #----------------------------------------------------------------------
  1057. #                      Non-dropdown states
  1058. #----------------------------------------------------------------------
  1059. proc tixComboBox:GoState-n0 {w} {
  1060.     upvar #0 $w data
  1061. }
  1062.  
  1063. proc tixComboBox:GoState-n1 {w} {
  1064.     upvar #0 $w data
  1065.  
  1066.     tixComboBox:Invoke $w
  1067.     tixComboBox:GoState n0 $w
  1068. }
  1069.  
  1070. proc tixComboBox:GoState-n3 {w dir} {
  1071.     upvar #0 $w data
  1072.  
  1073.     tixComboBox:HandleDirKey $w $dir
  1074.     tixComboBox:GoState n0 $w
  1075. }
  1076.  
  1077. proc tixComboBox:GoState-n4 {w} {
  1078.     upvar #0 $w data
  1079.  
  1080.     tixComboBox:Cancel $w
  1081.     tixComboBox:GoState n0 $w
  1082. }
  1083.  
  1084. proc tixComboBox:GoState-n6 {w x y X Y} {
  1085.     upvar #0 $w data
  1086.  
  1087.     tixComboBox:LbSelect $w $x $y $X $Y
  1088. }
  1089.  
  1090. #----------------------------------------------------------------------
  1091. #                      General State Manipulation
  1092. #----------------------------------------------------------------------
  1093. proc tixComboBox:GoState {s w args} {
  1094.     upvar #0 $w data
  1095.  
  1096.     tixComboBox:SetState $w $s
  1097.     eval tixComboBox:GoState-$s $w $args
  1098. }
  1099.  
  1100. proc tixComboBox:SetState {w s} {
  1101.     upvar #0 $w data
  1102.  
  1103. #    catch {puts [info level -2]}
  1104. #    puts "setting state $data(state) --> $s"
  1105.     set data(state) $s
  1106. }
  1107.  
  1108. proc tixComboBox:StateError {w} {
  1109.     upvar #0 $w data
  1110.  
  1111. #    error "wrong state $data(state)"
  1112. }
  1113.  
  1114. #----------------------------------------------------------------------
  1115. #                      Listbox handling
  1116. #----------------------------------------------------------------------
  1117.  
  1118. # Set a selection if there isn't one. Returns true if there was already
  1119. # a good selection inside the listbox
  1120. #
  1121. proc tixComboBox:CheckListboxSelection {w} {
  1122.     upvar #0 $w data
  1123.  
  1124.     if {[$data(w:listbox) curselection] == ""} {
  1125.     if {$data(curIndex) == ""} {
  1126.         set data(curIndex) 0
  1127.     }
  1128.  
  1129.     $data(w:listbox) activate $data(curIndex)
  1130.     $data(w:listbox) selection clear 0 end
  1131.     $data(w:listbox) selection set $data(curIndex)
  1132.     $data(w:listbox) see $data(curIndex)
  1133.     return 0
  1134.     } else {
  1135.     return 1
  1136.     }
  1137. }
  1138.  
  1139. proc tixComboBox:SetSelectionFromListbox {w} {
  1140.     upvar #0 $w data
  1141.  
  1142.     set string [$data(w:listbox) get $data(curIndex)] 
  1143.     tixComboBox:SetSelection $w $string
  1144.     tixComboBox:UpdateListboxSelection $w $data(curIndex)
  1145. }
  1146.  
  1147. proc tixComboBox:LbGetSelection {w} {
  1148.     upvar #0 $w data
  1149.     set index [tixComboBox:LbIndex $w emptyOK]
  1150.  
  1151.     if {$index >=0} {
  1152.     return [$data(w:listbox) get $index]
  1153.     } else {
  1154.     return ""
  1155.     }
  1156. }
  1157.  
  1158. proc tixComboBox:LbSelect {w x y X Y} {
  1159.     upvar #0 $w data
  1160.  
  1161.     set index [tixComboBox:LbIndex $w emptyOK]
  1162.     if {$index == ""} {
  1163.     set index [$data(w:listbox) nearest $y]
  1164.     }
  1165.  
  1166.     if {$index >= 0} {
  1167.     if {"x[focus -lastfor $data(w:entry)]" != "x$data(w:entry)" &&
  1168.         "x[focus -lastfor $data(w:entry)]" != "x$data(w:listbox)"} {
  1169.         focus $data(w:entry)
  1170.     }
  1171.  
  1172.     set string [$data(w:listbox) get $index] 
  1173.     tixComboBox:SetSelection $w $string
  1174.  
  1175.     tixComboBox:UpdateListboxSelection $w $index
  1176.     }
  1177. }
  1178.  
  1179. #----------------------------------------------------------------------
  1180. # Internal commands
  1181. #----------------------------------------------------------------------
  1182. proc tixComboBox:CrossBtn {w} {
  1183.     upvar #0 $w data
  1184.  
  1185.     $data(w:entry) delete 0 end
  1186.     tixComboBox:ClearListboxSelection $w
  1187.     tixComboBox:SetSelection $w ""
  1188. }
  1189.  
  1190. #--------------------------------------------------
  1191. #        Popping up list shell
  1192. #--------------------------------------------------
  1193.  
  1194. # Popup the listbox and grab
  1195. #
  1196. #
  1197. proc tixComboBox:Popup {w} {
  1198.     global tcl_platform
  1199.     upvar #0 $w data
  1200.  
  1201.     if {![winfo ismapped $data(w:root)]} {
  1202.     return
  1203.     }
  1204.  
  1205.     #---------------------------------------------------------------------
  1206.     #                 Pop up
  1207.     #
  1208.     if {$data(-listcmd) != ""} {
  1209.     # This option allows the user to fill in the listbox on demand
  1210.     #
  1211.     tixEvalCmdBinding $w $data(-listcmd)
  1212.     }
  1213.  
  1214.     # calculate the size
  1215.     set  y [winfo rooty $data(w:entry)]
  1216.     incr y [winfo height $data(w:entry)]
  1217.     incr y 3
  1218.  
  1219.     set bd [$data(w:shell) cget -bd]
  1220. #   incr bd [$data(w:shell) cget -highlightthickness]
  1221.     set height [expr [winfo reqheight $data(w:slistbox)] + 2*$bd]
  1222.  
  1223.     set x1 [winfo rootx $data(w:entry)]
  1224.     if {$data(-listwidth) == ""} {
  1225.     if [winfo ismapped $data(w:arrow)] {
  1226.         set x2  [winfo rootx $data(w:arrow)]
  1227.         if {$x2 >= $x1} {
  1228.         incr x2 [winfo width $data(w:arrow)]
  1229.         set width  [expr "$x2 - $x1"]
  1230.         } else {
  1231.         set width  [winfo width $data(w:entry)]
  1232.         set x2 [expr $x1 + $width]
  1233.         }
  1234.     } else {
  1235.         set width  [winfo width $data(w:entry)]
  1236.         set x2 [expr $x1 + $width]
  1237.     }
  1238.     } else {
  1239.     set width $data(-listwidth)
  1240.     set x2 [expr $x1 + $width]
  1241.     }
  1242.  
  1243.     set reqwidth [winfo reqwidth $data(w:shell)]
  1244.     if {$reqwidth < $width} {
  1245.     set reqwidth $width
  1246.     } else {
  1247.     if {$reqwidth > [expr $width *3]} {
  1248.         set reqwidth [expr $width *3]
  1249.     }
  1250.     if {$reqwidth > [winfo vrootwidth .]} {
  1251.         set reqwidth [winfo vrootwidth .]
  1252.     }
  1253.     }
  1254.     set width $reqwidth
  1255.  
  1256.  
  1257.     # If the listbox is too far right, pull it back to the left
  1258.     #
  1259.     set scrwidth [winfo vrootwidth .]
  1260.     if {$x2 > $scrwidth} {
  1261.     set x1 [expr $scrwidth - $width]
  1262.     }
  1263.  
  1264.     # If the listbox is too far left, pull it back to the right
  1265.     #
  1266.     if {$x1 < 0} {
  1267.     set x1 0
  1268.     }
  1269.  
  1270.     # If the listbox is below bottom of screen, put it upwards
  1271.     #
  1272.     set scrheight [winfo vrootheight .]
  1273.     set bottom [expr $y+$height]
  1274.     if {$bottom > $scrheight} {
  1275.     set y [expr $y-$height-[winfo height $data(w:entry)]-5]
  1276.     }
  1277.  
  1278.     # OK , popup the shell
  1279.     #
  1280.  
  1281.     wm geometry $data(w:shell) $reqwidth\x$height+$x1+$y
  1282.     if {$tcl_platform(platform) == "windows"} {
  1283.       update
  1284.     }
  1285.     wm deiconify $data(w:shell)
  1286.     if {$tcl_platform(platform) == "windows"} {
  1287.       update
  1288.     }
  1289.  
  1290.     raise $data(w:shell)
  1291.     focus $data(w:entry)
  1292.     set data(popped) 1
  1293.  
  1294.     tixComboBox:Grab $w
  1295. }
  1296.  
  1297. proc tixComboBox:SetCursor {w cursor} {
  1298.     upvar #0 $w data
  1299.  
  1300.     $w config -cursor $cursor
  1301. }
  1302.  
  1303. proc tixComboBox:Popdown {w} {
  1304.     upvar #0 $w data
  1305.  
  1306.     wm withdraw $data(w:shell)
  1307.     tixComboBox:SetCursor $w ""
  1308. }
  1309.  
  1310. # Grab the server so that user cannot move the windows around
  1311. proc tixComboBox:Grab {w} {
  1312.     upvar #0 $w data
  1313.  
  1314.     tixComboBox:SetCursor $w arrow
  1315.     catch {
  1316.     # We catch here because grab may fail under a lot of circumstances
  1317.     # Just don't want to break the code ...
  1318.     case $data(-grab) {
  1319.         global {
  1320.         tixPushGrab -global $data(w:root)
  1321.         }
  1322.         local {
  1323.         tixPushGrab $data(w:root)
  1324.         }
  1325.     }
  1326.     }
  1327. }
  1328.  
  1329. proc tixComboBox:Ungrab {w} {
  1330.     upvar #0 $w data
  1331.  
  1332.     case $data(-grab) {
  1333.     global {
  1334.         tixPopGrab
  1335.     }
  1336.     local {
  1337.         tixPopGrab
  1338.     }
  1339.     }
  1340. }
  1341.  
  1342. #----------------------------------------------------------------------
  1343. #         Alignment
  1344. #----------------------------------------------------------------------
  1345. # The following two routines can emulate a "right align mode" for the
  1346. # entry in the combo box.
  1347.  
  1348. proc tixComboBox:EntryAlignEnd {w} {
  1349.     upvar #0 $w data
  1350.     $data(w:entry) xview end
  1351. }
  1352.  
  1353.  
  1354. proc tixComboBox:Destructor {w} {
  1355.     upvar #0 $w data
  1356.  
  1357.     tixUnsetMegaWidget $data(w:entry)
  1358.     tixVariable:DeleteVariable $w
  1359.  
  1360.     # Chain this to the superclass
  1361.     #
  1362.     tixChainMethod $w Destructor
  1363. }
  1364.  
  1365.  
  1366. #----------------------------------------------------------------------
  1367. #                           CONFIG OPTIONS
  1368. #----------------------------------------------------------------------
  1369.  
  1370. proc tixComboBox:config-state {w value} {
  1371.     upvar #0 $w data
  1372.     catch {if {"x[$data(w:arrow) cget -state]" == "x$value"} {
  1373.     set a 1
  1374.     }}
  1375.     if [info exists a] {
  1376.     return
  1377.     }
  1378.  
  1379.     catch {$data(w:arrow) config -state $value}
  1380.     catch {$data(w:tick)  config -state $value}
  1381.     catch {$data(w:cross) config -state $value}
  1382.     catch {$data(w:slistbox) config -state $value}
  1383.  
  1384.     if ![string compare $value normal] {
  1385.     set fg [$data(w:arrow) cget -fg]
  1386.     set entryFg $data(entryfg)
  1387.     set lbSelFg [lindex [$data(w:listbox) config -selectforeground] 3]
  1388.     set lbSelBg [lindex [$data(w:listbox) config -selectbackground] 3]
  1389.     set entrySelFg [lindex [$data(w:entry) config -selectforeground] 3]
  1390.     set entrySelBg [lindex [$data(w:entry) config -selectbackground] 3]
  1391.     } else {
  1392.     set fg [$data(w:arrow) cget -disabledforeground]
  1393.     set entryFg $data(-disabledforeground)
  1394.     set lbSelFg $entryFg
  1395.     set lbSelBg [$data(w:listbox) cget -bg]
  1396.     set entrySelFg $entryFg
  1397.     set entrySelBg [$data(w:entry) cget -bg]
  1398.     }
  1399.     if [string compare $fg ""] {
  1400.     $data(w:label) config -fg $fg
  1401.     $data(w:listbox) config -fg $fg -selectforeground $lbSelFg \
  1402.       -selectbackground $lbSelBg
  1403.     }
  1404.     $data(w:entry) config -fg $entryFg -selectforeground $entrySelFg \
  1405.       -selectbackground $entrySelBg
  1406.  
  1407.     if ![string compare $value normal] {
  1408.     if {$data(-editable)} {
  1409.         $data(w:entry) config -state normal
  1410.     }
  1411.         $data(w:entry) config -takefocus 1
  1412.     } else {
  1413.     if {$data(-editable)} {
  1414.        $data(w:entry) config -state disabled
  1415.         }
  1416.         $data(w:entry) config -takefocus 0
  1417.     }
  1418. }
  1419.  
  1420. proc tixComboBox:config-value {w value} {
  1421.     upvar #0 $w data
  1422.  
  1423.     tixComboBox:SetValue $w $value
  1424.  
  1425.     set data(-selection) $value
  1426.  
  1427.     if {"x[tixComboBox:LbGetSelection $w]" != "x$value"} {
  1428.     tixComboBox:ClearListboxSelection $w
  1429.     }
  1430. }
  1431.  
  1432. proc tixComboBox:config-selection {w value} {
  1433.     upvar #0 $w data
  1434.  
  1435.     tixComboBox:SetSelection $w $value
  1436.  
  1437.     if {"x[tixComboBox:LbGetSelection $w]" != "x$value"} {
  1438.     tixComboBox:ClearListboxSelection $w
  1439.     }
  1440. }
  1441.  
  1442. proc tixComboBox:config-variable {w arg} {
  1443.     upvar #0 $w data
  1444.  
  1445.     if [tixVariable:ConfigVariable $w $arg] {
  1446.        # The value of data(-value) is changed if tixVariable:ConfigVariable 
  1447.        # returns true
  1448.        set data(-selection) $data(-value)
  1449.        tixComboBox:SetValue $w $data(-value) 1
  1450.     }
  1451.     catch {
  1452.     unset data(varInited)
  1453.     }
  1454.     set data(-variable) $arg
  1455. }
  1456.  
  1457.  
  1458. #----------------------------------------------------------------------
  1459. #                     WIDGET COMMANDS
  1460. #----------------------------------------------------------------------
  1461. proc tixComboBox:align {w args} {
  1462.     upvar #0 $w data
  1463.  
  1464.     if {$data(-anchor) == "e"} {
  1465.     tixComboBox:EntryAlignEnd $w
  1466.     }
  1467. }
  1468.  
  1469. proc tixComboBox:addhistory {w value} {
  1470.     upvar #0 $w data
  1471.  
  1472.     tixComboBox:insert $w 0 $value
  1473.     $data(w:listbox) selection clear 0 end
  1474.  
  1475.     if {$data(-prunehistory)} {
  1476.     # Prune from the end
  1477.     # 
  1478.     set max [$data(w:listbox) size]
  1479.     if {$max <= 1} {
  1480.         return
  1481.     }
  1482.     for {set i [expr $max -1]} {$i >= 1} {incr i -1} {
  1483.         if {"x[$data(w:listbox) get $i]" == "x$value"} {
  1484.         $data(w:listbox) delete $i
  1485.         break
  1486.         }
  1487.     }
  1488.     }
  1489. }
  1490.  
  1491. proc tixComboBox:appendhistory {w value} {
  1492.     upvar #0 $w data
  1493.  
  1494.     tixComboBox:insert $w end $value
  1495.     $data(w:listbox) selection clear 0 end
  1496.  
  1497.     if {$data(-prunehistory)} {
  1498.     # Prune from the end
  1499.     # 
  1500.     set max [$data(w:listbox) size]
  1501.     if {$max <= 1} {
  1502.         return
  1503.     }
  1504.     for {set i [expr $max -2]} {$i >= 0} {incr i -1} {
  1505.         if {"x[$data(w:listbox) get $i]" == "x$value"} {
  1506.         $data(w:listbox) delete $i
  1507.         break
  1508.         }
  1509.     }
  1510.     }
  1511. }
  1512.  
  1513. proc tixComboBox:insert {w index newitem} {
  1514.     upvar #0 $w data
  1515.  
  1516.     $data(w:listbox) insert $index $newitem
  1517.  
  1518.     if {$data(-history) && $data(-historylimit) != ""} {
  1519.     if {"x[$data(w:listbox) size]"  == "x$data(-historylimit)"} {
  1520.         $data(w:listbox) delete 0
  1521.     }
  1522.     }
  1523. }
  1524.  
  1525. proc tixComboBox:pick {w index} {
  1526.     upvar #0 $w data
  1527.  
  1528.     $data(w:listbox) activate $index
  1529.     $data(w:listbox) selection clear 0 end
  1530.     $data(w:listbox) selection set active
  1531.     $data(w:listbox) see active
  1532.     set text [$data(w:listbox) get $index]
  1533.  
  1534.     tixComboBox:SetValue $w $text
  1535.  
  1536.     set data(curIndex) $index
  1537. }
  1538.  
  1539. proc tixComboBox:invoke {w} {
  1540.     tixComboBox:Invoke $w
  1541. }
  1542.  
  1543. proc tixComboBox:popdown {w} {
  1544.     upvar #0 $w data
  1545.  
  1546.     if {$data(-dropdown)} {
  1547.     tixComboBox:Popdown $w
  1548.     }
  1549. }
  1550.